package com.yunpeng.aidevice.dao.service.impl;

import com.yunpeng.aidevice.common.constant.ConfigConstantValues;
import com.yunpeng.aidevice.dao.service.ICodeGenerateCommonService;
import com.yunpeng.aidevice.dao.service.IPermissionService;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.cache.util.DistributedLockHelper;
import com.yunpeng.common.exception.BizException;
import com.yunpeng.aidevice.dao.mapper.entity.OrganizationMapper;
import com.yunpeng.aidevice.dao.mapper.entity.PermissionMapper;
import com.yunpeng.aidevice.dao.mapper.relation.FunctionsNodeRelationPermissionsMapper;
import com.yunpeng.aidevice.dao.mapper.relation.OrganizationPermissionMapper;
import com.yunpeng.aidevice.dao.mapper.relation.RolePermissionMapper;
import com.yunpeng.aidevice.dao.mapper.relation.UserOwnPermissionMapper;
import com.yunpeng.aidevice.dao.model.entity.OrganizationDO;
import com.yunpeng.aidevice.dao.model.entity.PermissionDO;
import com.yunpeng.aidevice.dao.model.relation.OrganizationPermissionDO;
import com.yunpeng.aidevice.dao.model.relation.RolePermissionDO;
import com.yunpeng.aidevice.dao.model.relation.UserOwnPermissionDO;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * PermissionServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-15
 */
@Service
public class PermissionServiceImpl implements IPermissionService {

    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(PermissionServiceImpl.class);

    /**
     * 当前服务的实体表名
     */
    private static final String TABLE_NAME = "t_ai_device_permission";

    @Resource
    private ICodeGenerateCommonService codeGenerateCommonService;

    @Resource
    private PermissionMapper permissionMapper;

    @Resource
    private UserOwnPermissionMapper userOwnPermissionMapper;

    @Resource
    private OrganizationPermissionMapper organizationPermissionMapper;

    @Resource
    private RolePermissionMapper rolePermissionMapper;

    @Resource
    private FunctionsNodeRelationPermissionsMapper functionsNodeRelationPermissionsMapper;

    @Resource
    private OrganizationMapper organizationMapper;

    @Override
    /**
     * 根据权限代码获取权限实体
     *
     * @param permissionCode
     * @return
     */
    public PermissionDO getByCode(String permissionCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return null;
        }
        return permissionMapper.getByCode(permissionCode);
    }

    @Override
    /**
     * 新增权限
     *
     * @param name         权限名称
     * @param operatorCode 操作人代码
     * @return
     */
    public Boolean addNew(String name, String operatorCode) {
        if (StringUtils.isBlank(name)) {
            return false;
        }
        PermissionDO permissionDO = new PermissionDO();
        permissionDO.initForNew(operatorCode);
        permissionDO.setName(name);
        permissionDO.setDisabled(false);
        if (DistributedLockHelper.INSTANCE.getLock(TABLE_NAME, ConfigConstantValues.APPLICATION_NAME)) {
            permissionDO.setCode(codeGenerateCommonService.generateCode(TABLE_NAME));
            try {
                permissionMapper.add(permissionDO);
                return true;
            } catch (Exception ex) {
                LOGGER.error("save permission info error : {}", permissionDO, ex);
                throw new BizException(ResultCodeEnum.SAVE_DATA_FAILED);
            } finally {
                codeGenerateCommonService.holdCountMinus(TABLE_NAME);
                DistributedLockHelper.INSTANCE.unlock(TABLE_NAME, ConfigConstantValues.APPLICATION_NAME);
            }
        } else {
            return false;
        }
    }

    @Override
    /**
     * 删除权限项
     *
     * @param permissionCode
     * @param operatorCode
     * @return
     */
    public Boolean remove(String permissionCode, String operatorCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        PermissionDO permissionDO = permissionMapper.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "该权限项不存在！");
        }
        permissionMapper.delete(permissionDO.getId());
        functionsNodeRelationPermissionsMapper.deleteByPermission(permissionCode);
        return true;
    }

    @Override
    /**
     * 禁用权限
     *
     * @param permissionCode
     * @param operatorCode
     * @return
     */
    public Boolean disabled(String permissionCode, String operatorCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        PermissionDO permissionDO = permissionMapper.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "该权限项不存在！");
        }
        if (permissionDO.getDisabled()) {
            return true;
        }
        Map<String, Object> updateParam = new HashMap<>(16);
        updateParam.put("update_time", new Date());
        updateParam.put("updater", operatorCode);
        updateParam.put("disabled", 1);
        permissionMapper.update(permissionDO.getId(), updateParam);
        return true;
    }

    @Override
    /**
     * 启用权限
     *
     * @param permissionCode
     * @param operatorCode
     * @return
     */
    public Boolean enabled(String permissionCode, String operatorCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        PermissionDO permissionDO = permissionMapper.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "该权限项不存在！");
        }
        if (!permissionDO.getDisabled()) {
            return true;
        }
        Map<String, Object> updateParam = new HashMap<>(16);
        updateParam.put("update_time", new Date());
        updateParam.put("updater", operatorCode);
        updateParam.put("disabled", 0);
        permissionMapper.update(permissionDO.getId(), updateParam);
        return true;
    }

    @Override
    /**
     * 绑定用户权限关系的保存
     *
     * @param saveData
     * @return
     */
    public Boolean bindUserPermission(UserOwnPermissionDO saveData) {
        if (saveData == null) {
            return false;
        }
        userOwnPermissionMapper.add(saveData);
        return true;
    }

    @Override
    /**
     * 清除用户和权限绑定
     *
     * @param userCode
     * @param permissionCode
     * @return
     */
    public Boolean unbindUserPermission(String userCode, String permissionCode) {
        if (StringUtils.isBlank(userCode)) {
            return false;
        }
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        userOwnPermissionMapper.clearBind(permissionCode, userCode);
        return true;
    }


    @Override
    /**
     * 根据用户代码查询用户目前依然生效的权限绑定数据
     *
     * @param userCode 用户代码
     * @return
     */
    public List<UserOwnPermissionDO> queryUserPermissionListByUser(String userCode) {
        if (StringUtils.isBlank(userCode)) {
            return null;
        }
        return userOwnPermissionMapper.queryPermissionListByUser(userCode, new Date());
    }

    @Override
    /**
     * 根据权限代码查询目前依然生效的权限绑定数据
     *
     * @param permissionCode 权限代码
     * @return
     */
    public List<UserOwnPermissionDO> queryUserPermissionListByPermission(String permissionCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return null;
        }
        return userOwnPermissionMapper.queryListByPermission(permissionCode, new Date());
    }

    @Override
    /**
     * 根据角色代码查询目前生效的角色权限绑定数据
     *
     * @param roleCode 角色代码
     * @return
     */
    public List<RolePermissionDO> queryRolePermissionListByRole(String roleCode) {
        if (StringUtils.isBlank(roleCode)) {
            return null;
        }
        return rolePermissionMapper.queryListByRole(roleCode);
    }

    @Override
    /**
     * 根据权限代码查询目前生效的角色权限绑定数据
     *
     * @param permissionCode 权限代码
     * @return
     */
    public List<RolePermissionDO> queryRolePermissionListByPermission(String permissionCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return null;
        }
        return rolePermissionMapper.queryListByPermission(permissionCode);
    }

    @Override
    /**
     * 根据权限代码查询目前生效的组织权限绑定数据
     *
     * @param permissionCode 权限代码
     * @return
     */
    public List<OrganizationPermissionDO> queryOrgPermissionListByPermission(String permissionCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return null;
        }
        return organizationPermissionMapper.queryListByPermission(permissionCode, new Date());
    }

    @Override
    /**
     * 根据组织代码查询目前生效的权限绑定数据
     *
     * @param orgCode 组织机构代码
     * @return
     */
    public List<OrganizationPermissionDO> queryOrgPermissionListByOrg(String orgCode) {
        if (StringUtils.isBlank(orgCode)) {
            return null;
        }
        return organizationPermissionMapper.queryListByOrganization(orgCode, new Date());
    }

    @Override
    /**
     * 绑定权限到组织机构
     *
     * @param permissionCode 权限代码
     * @param orgCode        组织机构代码
     * @param startTime      起始生效时间
     * @param endTime        生效截止时间
     * @param operatorCode   操作人代码
     * @return
     */
    public Boolean bindPermissionToOrg(String permissionCode, String orgCode, Date startTime, Date endTime, String operatorCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        if (StringUtils.isBlank(orgCode)) {
            return false;
        }
        PermissionDO permissionDO = permissionMapper.getByCode(permissionCode);
        if (permissionDO == null || permissionDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "该权限项不存在！");
        }
        OrganizationDO organizationDO = organizationMapper.getByCode(orgCode);
        if (organizationDO == null || organizationDO.getId() == null) {
            throw new BizException(ResultCodeEnum.NOT_EXISTS_DATA_FAILED, "该组织不存在！");
        }
        OrganizationPermissionDO organizationPermissionDO = new OrganizationPermissionDO();
        organizationPermissionDO.initForNew(operatorCode);
        organizationPermissionDO.setOrganizationCode(organizationDO.getCode());
        organizationPermissionDO.setOrganizationName(organizationDO.getName());
        organizationPermissionDO.setPermissionName(permissionDO.getName());
        organizationPermissionDO.setPermissionCode(permissionDO.getCode());
        organizationPermissionDO.setStartDate(startTime);
        organizationPermissionDO.setEndDate(endTime);
        organizationPermissionMapper.add(organizationPermissionDO);
        return true;
    }

    @Override
    /**
     * 解除组织机构权限绑定
     *
     * @param permissionCode 权限代码
     * @param orgCode        组织机构代码
     * @return
     */
    public Boolean unbindPermissionFromOrg(String permissionCode, String orgCode) {
        if (StringUtils.isBlank(permissionCode)) {
            return false;
        }
        if (StringUtils.isBlank(orgCode)) {
            return false;
        }
        organizationPermissionMapper.deleteByOrgPermission(permissionCode, orgCode);
        return true;
    }

}
